package nz.ac.massey.cs.webtech.s_15273550.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

@WebServlet(name = "BlackJackEngineServlet", value = "/jack/*")
public class BlackJackEngineServlet extends HttpServlet {
    static final String DB_URL = "jdbc:mysql://47.94.143.28:3306/normal";
    static final String USER = "root";
    static final String PASS = "123456";

    public String getGameStats(boolean addGame, boolean addUserWon) {
        Connection conn = null;
        Statement stmt = null;
        int gamePlayed = 0;
        int userWon = 0;
        String resStr = "";
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT game_played, user_won FROM black_jack_stats where id=1";
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                gamePlayed = rs.getInt("game_played");
                userWon = rs.getInt("user_won");
            }
            synchronized (this) {
                if (addGame) {
                    gamePlayed += 1;
                    sql = "update black_jack_stats set game_played = " + gamePlayed + " where id=1";
                    stmt.executeUpdate(sql);
                }
                if (addUserWon) {
                    userWon += 1;
                    sql = "update black_jack_stats set user_won = " + userWon + " where id=1";
                    stmt.executeUpdate(sql);
                }
            }

            rs.close();
            stmt.close();
            conn.close();
        } catch (Exception se) {
            se.printStackTrace();
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
            } catch (SQLException ignored) {
            }
            try {
                if (conn != null)
                    conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
        if (gamePlayed == 0) {
            resStr = "games played: " + gamePlayed + "  user win percentage: 0%";
        } else {
            double f1 = new BigDecimal((float) userWon / gamePlayed).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            resStr = "games played: " + gamePlayed + "  user win percentage: " + f1 * 100 + "%";
        }
        return resStr;
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        response.setContentType("application/json; charset=utf-8");
        String baseUri = request.getRequestURI();
        JSONObject res = new JSONObject();
        res.put("status", 0);
        res.put("msg", "");
        res.put("data", "success");
        GamingRoom gamingRoom = (GamingRoom) request.getSession().getAttribute("gaming");
        if (baseUri.endsWith("/state")) {
            if (gamingRoom == null) {
                res.put("status", 1);
                res.put("msg", "404 Not Found");
            } else {
                Player player = gamingRoom.getPlayer();
                Dealer dealer = gamingRoom.getDealer();
                List<Card> cardsDealer = dealer.getCardsInHand();
                List<Card> cardsPlayer = player.getCardsInHand();
                JSONObject data = new JSONObject();
                data.put("cardsPlayer", cardsPlayer);
                data.put("cardsDealer", cardsDealer);
                res.put("data", data);
            }
            out.print(res.toString());
        } else if (baseUri.endsWith("/possiblemoves")) {
            if (gamingRoom == null) {
                res.put("status", 1);
                res.put("msg", "404 Not Found");
            } else {
                Player player = gamingRoom.getPlayer();
                boolean over = BlackJackRule.isPlayerOver(player);
                ArrayList<String> list = new ArrayList<>();
                list.add("stand");
                if (!over) {
                    list.add("hit");
                }
                res.put("data", list);
            }
            out.print(res.toString());
        } else if (baseUri.endsWith("/stats")) {
            response.setContentType("text/plain; charset=utf-8");
            String resStr = getGameStats(false, false);
            out.print(resStr);
        }
        out.flush();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        String baseUri = request.getRequestURI();//
        //
        PrintWriter writer = response.getWriter();
        JSONObject res = new JSONObject();
        res.put("status", 0);
        res.put("msg", "");
        res.put("data", "success");
        GamingRoom gamingRoom = (GamingRoom) request.getSession().getAttribute("gaming");
        if (baseUri.endsWith("/start")) {
            GamingRoom gamingRoomNew = new GamingRoom();
            gamingRoomNew.startGame();
//            gameStats.gamesPlayed += 1;
            getGameStats(true, false);
            request.getSession().setAttribute("gaming", gamingRoomNew);
            res.put("data", "ok");
            writer.print(res.toString());
        } else if (baseUri.endsWith("/move/hit")) {
            response.setContentType("text/plain; charset=utf-8");
            if (gamingRoom == null) {
                writer.print("404 Not Found");
                writer.flush();
                writer.close();
                return;
            }
            if (!gamingRoom.getTurn().equals("user")) {
                writer.print("400 Bad Request");
                writer.flush();
                writer.close();
                return;
            }
            Player player = gamingRoom.getPlayer();
            player.getCardsInHand().add(gamingRoom.getDeck().getOne());
            gamingRoom.setTurn("computer");
            gamingRoom.dealerStep();
        } else if (baseUri.endsWith("/move/stand")) {
            response.setContentType("text/plain; charset=utf-8");
            if (gamingRoom == null) {
                writer.print("404 Not Found");
                writer.flush();
                writer.close();
                return;
            }
            Player player = gamingRoom.getPlayer();
            player.setStand(true);
            gamingRoom.setTurn("computer");
            gamingRoom.dealerStep();
        } else if (baseUri.endsWith("/won")) {
            response.setContentType("text/plain; charset=utf-8");
            String resStr;
            if (gamingRoom == null) {
                resStr = "404 Not Found";
            } else {
                Player player = gamingRoom.getPlayer();
                Dealer dealer = gamingRoom.getDealer();
                if (player.isStand() || player.getTotalPoints() > 21 || dealer.getTotalPoints() > 21) {
                    gamingRoom.dealerStep();
                    resStr = gamingRoom.decideWinner(player, dealer);
                } else {
                    resStr = "draw";
                }
            }
            if (resStr == "user") {
                getGameStats(false, true);
            }
            writer.print(resStr);
        }
        writer.flush();
        writer.close();
    }
}
